package com.company.oa.hr.service.employee.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.oa.common.exception.BusinessException;
import com.company.oa.hr.entity.employee.Attendance;
import com.company.oa.hr.entity.employee.Employee;
import com.company.oa.hr.mapper.employee.AttendanceMapper;
import com.company.oa.hr.service.employee.AttendanceService;
import com.company.oa.hr.service.employee.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class AttendanceServiceImpl extends ServiceImpl<AttendanceMapper, Attendance> implements AttendanceService {

    @Autowired
    private EmployeeService employeeService;

    @Override
    public IPage<Map<String, Object>> getAttendancePage(int page, int size, Attendance attendance) {
        // 实际项目中需要实现联表查询，这里简单返回
        Page<Attendance> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Attendance> queryWrapper = new LambdaQueryWrapper<>();
        
        if (attendance.getEmployeeId() != null) {
            queryWrapper.eq(Attendance::getEmployeeId, attendance.getEmployeeId());
        }
        
        if (attendance.getAttendanceDate() != null) {
            queryWrapper.eq(Attendance::getAttendanceDate, attendance.getAttendanceDate());
        }
        
        if (attendance.getStatus() != null) {
            queryWrapper.eq(Attendance::getStatus, attendance.getStatus());
        }
        
        queryWrapper.orderByDesc(Attendance::getAttendanceDate);
        
        IPage<Attendance> attendancePage = page(pageParam, queryWrapper);
        
        // 转换为Map结果集
        List<Map<String, Object>> records = new ArrayList<>();
        for (Attendance record : attendancePage.getRecords()) {
            Map<String, Object> map = new HashMap<>();
            map.put("attendance", record);
            
            // 获取员工信息
            Employee employee = employeeService.getById(record.getEmployeeId());
            if (employee != null) {
                map.put("employeeName", employee.getName());
                map.put("employeeNo", employee.getEmployeeNo());
            }
            
            records.add(map);
        }
        
        Page<Map<String, Object>> resultPage = new Page<>(attendancePage.getCurrent(), attendancePage.getSize(), attendancePage.getTotal());
        resultPage.setRecords(records);
        
        return resultPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean checkIn(Long employeeId) {
        // 检查员工是否存在
        Employee employee = employeeService.getById(employeeId);
        if (employee == null) {
            throw new BusinessException("员工不存在");
        }
        
        // 检查今日是否已签到
        Date today = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String todayStr = sdf.format(today);
        
        try {
            Date todayDate = sdf.parse(todayStr);
            
            LambdaQueryWrapper<Attendance> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Attendance::getEmployeeId, employeeId)
                       .eq(Attendance::getAttendanceDate, todayDate);
            
            Attendance existAttendance = getOne(queryWrapper);
            
            if (existAttendance != null) {
                throw new BusinessException("今日已签到");
            }
            
            // 创建签到记录
            Attendance attendance = new Attendance();
            attendance.setEmployeeId(employeeId);
            attendance.setAttendanceDate(todayDate);
            attendance.setCheckInTime(new Date());
            attendance.setStatus(1); // 已签到未签退
            attendance.setCreateTime(new Date());
            
            return save(attendance);
            
        } catch (Exception e) {
            throw new BusinessException("签到失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean checkOut(Long employeeId) {
        // 检查员工是否存在
        Employee employee = employeeService.getById(employeeId);
        if (employee == null) {
            throw new BusinessException("员工不存在");
        }
        
        // 检查今日是否已签到
        Date today = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String todayStr = sdf.format(today);
        
        try {
            Date todayDate = sdf.parse(todayStr);
            
            LambdaQueryWrapper<Attendance> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Attendance::getEmployeeId, employeeId)
                       .eq(Attendance::getAttendanceDate, todayDate);
            
            Attendance existAttendance = getOne(queryWrapper);
            
            if (existAttendance == null) {
                throw new BusinessException("今日未签到，无法签退");
            }
            
            if (existAttendance.getStatus() == 2) {
                throw new BusinessException("今日已签退");
            }
            
            // 更新签退记录
            Attendance attendance = new Attendance();
            attendance.setId(existAttendance.getId());
            attendance.setCheckOutTime(new Date());
            attendance.setStatus(2); // 已签到已签退
            attendance.setUpdateTime(new Date());
            
            return updateById(attendance);
            
        } catch (Exception e) {
            throw new BusinessException("签退失败: " + e.getMessage());
        }
    }

    @Override
    public Attendance getEmployeeAttendanceByDate(Long employeeId, Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(date);
        
        try {
            Date attendanceDate = sdf.parse(dateStr);
            
            LambdaQueryWrapper<Attendance> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Attendance::getEmployeeId, employeeId)
                       .eq(Attendance::getAttendanceDate, attendanceDate);
            
            return getOne(queryWrapper);
            
        } catch (Exception e) {
            throw new BusinessException("获取考勤记录失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getEmployeeMonthlyAttendance(Long employeeId, Date month) {
        // 获取月份的第一天和最后一天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(month);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDay = calendar.getTime();
        
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date lastDay = calendar.getTime();
        
        // 查询该月所有考勤记录
        LambdaQueryWrapper<Attendance> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Attendance::getEmployeeId, employeeId)
                   .ge(Attendance::getAttendanceDate, firstDay)
                   .le(Attendance::getAttendanceDate, lastDay)
                   .orderByAsc(Attendance::getAttendanceDate);
        
        List<Attendance> attendanceList = list(queryWrapper);
        
        // 统计考勤情况
        int totalDays = attendanceList.size();
        int normalDays = 0;
        int lateDays = 0;
        int earlyDays = 0;
        int absentDays = 0;
        
        for (Attendance attendance : attendanceList) {
            if (attendance.getStatus() == 2) { // 正常签到签退
                normalDays++;
            } else if (attendance.getStatus() == 3) { // 迟到
                lateDays++;
            } else if (attendance.getStatus() == 4) { // 早退
                earlyDays++;
            } else if (attendance.getStatus() == 5) { // 缺勤
                absentDays++;
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("employeeId", employeeId);
        result.put("month", month);
        result.put("totalDays", totalDays);
        result.put("normalDays", normalDays);
        result.put("lateDays", lateDays);
        result.put("earlyDays", earlyDays);
        result.put("absentDays", absentDays);
        result.put("attendanceList", attendanceList);
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchImportAttendance(List<Attendance> attendanceList) {
        if (attendanceList == null || attendanceList.isEmpty()) {
            return false;
        }
        
        return saveBatch(attendanceList);
    }
} 